home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1995 August
/
CICA - The Ultimate Collection of Shareware for Windows (Disc 2) (August 1995).iso
/
disc2
/
nt
/
source.exe
/
POSIX
/
ELVIS
/
OPTS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-08
|
15KB
|
681 lines
/* opts.c */
/* Author:
* Steve Kirkendall
* 14407 SW Teal Blvd. #C
* Beaverton, OR 97005
* kirkenda@cs.pdx.edu
*/
/* This file contains the code that manages the run-time options -- The
* values that can be modified via the "set" command.
*/
#include "config.h"
#include "vi.h"
#ifndef NULL
#define NULL (char *)0
#endif
extern char *getenv();
/* maximum width to permit for strings, including ="" */
#define MAXWIDTH 20
/* These are the default values of all options */
char o_autoindent[1] = {FALSE};
char o_autoprint[1] = {TRUE};
char o_autowrite[1] = {FALSE};
#ifndef NO_ERRLIST
char o_cc[30] = {CC_COMMAND};
#endif
#ifndef NO_CHARATTR
char o_charattr[1] = {FALSE};
#endif
char o_columns[3] = {80, 32, 255};
#ifndef NO_DIGRAPH
char o_digraph[1] = {FALSE};
#endif
char o_directory[30] = TMPDIR;
char o_edcompatible[1] = {FALSE};
char o_errorbells[1] = {TRUE};
char o_exrefresh[1] = {TRUE};
#ifndef NO_DIGRAPH
char o_flipcase[80]
# if CS_IBMPC
= {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
# endif
# if CS_LATIN1
/* initialized by initopts() */
# endif
;
#endif
#ifndef NO_SENTENCE
char o_hideformat[1] = {FALSE};
#endif
char o_ignorecase[1] = {FALSE};
#ifndef NO_EXTENSIONS
char o_inputmode[1] = {FALSE};
#endif
char o_keytime[3] = {2, 0, 5};
char o_keywordprg[80] = {KEYWORDPRG};
char o_lines[3] = {25, 2, 50}; /* More lines? Enlarge kbuf */
char o_list[1] = {FALSE};
#ifndef NO_MAGIC
char o_magic[1] = {TRUE};
#endif
#ifndef NO_ERRLIST
char o_make[30] = {MAKE_COMMAND};
#endif
#ifndef NO_MODELINE
char o_modeline[1] = {FALSE};
#endif
#ifndef NO_SENTENCE
char o_paragraphs[30] = "PPppIPLPQP";
#endif
#if MSDOS
char o_pcbios[1] = {TRUE};
#endif
char o_readonly[1] = {FALSE};
char o_report[3] = {5, 1, 127};
char o_scroll[3] = {12, 1, 127};
#ifndef NO_SENTENCE
char o_sections[30] = "NHSHSSSEse";
#endif
char o_shell[60] = SHELL;
char o_shiftwidth[3] = {8, 1, 255};
#ifndef NO_SHOWMATCH
char o_showmatch[1] = {FALSE};
#endif
#ifndef NO_SHOWMODE
char o_smd[1] = {FALSE};
#endif
char o_sidescroll[3] = {8, 1, 40};
char o_sync[1] = {NEEDSYNC};
char o_tabstop[3] = {8, 1, 40};
char o_term[30] = "?";
char o_vbell[1] = {TRUE};
char o_warn[1] = {TRUE};
char o_wrapmargin[3] = {0, 0, 255};
char o_wrapscan[1] = {TRUE};
/* The following describes the names & types of all options */
#define BOOL 0
#define NUM 1
#define STR 2
#define SET 0x01 /* this option has had its value altered */
#define CANSET 0x02 /* this option can be set at any time */
#define RCSET 0x06 /* this option can be set in a .exrc file only */
#define MR 0x40 /* does this option affect the way text is displayed? */
struct
{
char *name; /* name of an option */
char *nm; /* short name of an option */
char type; /* type of an option */
char flags; /* boolean: has this option been set? */
char *value; /* value */
}
opts[] =
{
/* name type flags redraw value */
{ "autoindent", "ai", BOOL, CANSET , o_autoindent },
{ "autoprint", "ap", BOOL, CANSET , o_autoprint },
{ "autowrite", "aw", BOOL, CANSET , o_autowrite },
#ifndef NO_ERRLIST
{ "cc", "cc", STR, CANSET , o_cc },
#endif
#ifndef NO_CHARATTR
{ "charattr", "ca", BOOL, CANSET | MR, o_charattr },
#endif
{ "columns", "co", NUM, SET , o_columns },
#ifndef NO_DIGRAPH
{ "digraph", "dig", BOOL, CANSET , o_digraph },
#endif
{ "directory", "dir", STR, RCSET , o_directory },
{ "edcompatible","ed", BOOL, CANSET , o_edcompatible },
{ "errorbells", "eb", BOOL, CANSET , o_errorbells },
{ "exrefresh", "er", BOOL, CANSET , o_exrefresh },
#ifndef NO_DIGRAPH
{ "flipcase", "fc", STR, CANSET , o_flipcase },
#endif
#ifndef NO_SENTENCE
{ "hideformat", "hf", BOOL, CANSET | MR, o_hideformat },
#endif
{ "ignorecase", "ic", BOOL, CANSET , o_ignorecase },
#ifndef NO_EXTENSIONS
{ "inputmode", "im", BOOL, CANSET , o_inputmode },
#endif
{ "keytime", "kt", NUM, CANSET , o_keytime },
{ "keywordprg", "kp", STR, CANSET , o_keywordprg },
{ "lines", "ls", NUM, SET , o_lines },
{ "list", "li", BOOL, CANSET | MR, o_list },
#ifndef NO_MAGIC
{ "magic", "ma", BOOL, CANSET , o_magic },
#endif
#ifndef NO_ERRLIST
{ "make", "mk", STR, CANSET , o_make },
#endif
#ifndef NO_MODELINE
{ "modeline", "ml", BOOL, CANSET , o_modeline },
#endif
#ifndef NO_SENTENCE
{ "paragraphs", "pa", STR, CANSET , o_paragraphs },
#endif
#if MSDOS
{ "pcbios", "pc", BOOL, SET , o_pcbios },
#endif
{ "readonly", "ro", BOOL, CANSET , o_readonly },
{ "report", "re", NUM, CANSET , o_report },
{ "scroll", "sc", NUM, CANSET , o_scroll },
#ifndef NO_SENTENCE
{ "sections", "se", STR, CANSET , o_sections },
#endif
{ "shell", "sh", STR, CANSET , o_shell },
#ifndef NO_SHOWMATCH
{ "showmatch", "sm", BOOL, CANSET , o_showmatch },
#endif
#ifndef NO_SHOWMODE
{ "showmode", "smd", BOOL, CANSET , o_smd },
#endif
{ "shiftwidth", "sw", NUM, CANSET , o_shiftwidth },
{ "sidescroll", "ss", NUM, CANSET , o_sidescroll },
{ "sync", "sy", BOOL, CANSET , o_sync },
{ "tabstop", "ts", NUM, CANSET | MR, o_tabstop },
{ "term", "te", STR, SET , o_term },
{ "vbell", "vb", BOOL, CANSET , o_vbell },
{ "warn", "wa", BOOL, CANSET , o_warn },
{ "wrapmargin", "wm", NUM, CANSET , o_wrapmargin },
{ "wrapscan", "ws", BOOL, CANSET , o_wrapscan },
{ NULL, NULL, 0, CANSET, NULL }
};
/* This function initializes certain options from environment variables, etc. */
void initopts()
{
char *val;
int i;
/* set some stuff from environment variables */
#if MSDOS
if (val = getenv("COMSPEC")) /* yes, ASSIGNMENT! */
#else
if (val = getenv("SHELL")) /* yes, ASSIGNMENT! */
#endif
{
strcpy(o_shell, val);
}
#if ANY_UNIX || DF_POSIX
if (val = getenv("TERM")) /* yes, ASSIGNMENT! */
{
strcpy(o_term, val);
}
#endif
#if TOS
val = "vt52";
strcpy(o_term, val);
#endif
#if MSDOS
if ((val = getenv("TERM")) /* yes, ASSIGNMENT! */
&& strcmp(val, "pcbios"))
{
strcpy(o_term, val);
o_pcbios[0] = 0;
}
else
{
strcpy(o_term, "pcbios");
o_pcbios[0] = 1;
}
#endif
#if MSDOS || TOS || WIN_NT
if ((val = getenv("TMP")) /* yes, ASSIGNMENT! */
|| (val = getenv("TEMP")))
strcpy(o_directory, val);
#endif
*o_scroll = LINES / 2 - 1;
/* disable the vbell option if we don't know how to do a vbell */
if (!has_VB)
{
for (i = 0; opts[i].value != o_vbell; i++)
{
}
opts[i].flags &= ~CANSET;
*o_vbell = FALSE;
}
#ifndef NO_DIGRAPH
# ifdef CS_LATIN1
for (i = 0, val = o_flipcase; i < 32; i++)
{
/* leave out the multiply/divide symbols */
if (i == 23)
continue;
/* add upper/lowercase pair */
*val++ = i + 0xc0;
*val++ = i + 0xe0;
}
*val = '\0';
# endif /* CS_LATIN1 */
#endif /* not NO_DIGRAPH */
}
/* This function lists the current values of all options */
void dumpopts(all)
int all; /* boolean: dump all options, or just set ones? */
{
#ifndef NO_OPTCOLS
int i, j, k;
char nbuf[4]; /* used for converting numbers to ASCII */
int widths[5]; /* width of each column, including gap */
int ncols; /* number of columns */
int nrows; /* number of options per column */
int nset; /* number of options to be output */
int width; /* width of a particular option */
int todump[50]; /* indicies of options to be dumped */
/* step 1: count the number of set options */
for (nset = i = 0; opts[i].name; i++)
{
if (all || (opts[i].flags & SET))
{
todump[nset++] = i;
}
}
/* step two: try to use as many columns as possible */
for (ncols = (nset > 5 ? 5 : nset); ncols > 1; ncols--)
{
/* how many would go in this column? */
nrows = (nset + ncols - 1) / ncols;
/* figure out the width of each column */
for (i = 0; i < ncols; i++)
{
widths[i] = 0;
for (j = 0, k = nrows * i; j < nrows && k < nset; j++, k++)
{
/* figure out the width of a particular option */
switch (opts[todump[k]].type)
{
case BOOL:
if (!*opts[todump[k]].value)
width = 2;
else
width = 0;
break;
case STR:
width = 3 + strlen(opts[todump[k]].value);
if (width > MAXWIDTH)
width = MAXWIDTH;
break;
case NUM:
width = 4;
break;
}
width += strlen(opts[todump[k]].name);
/* if this is the widest so far, widen col */
if (width > widths[i])
{
widths[i] = width;
}
}
}
/* if the total width is narrow enough, then use it */
for (width = -2, i = 0; i < ncols; i++)
{
width += widths[i] + 2;
}
if (width < COLS - 1)
{
break;
}
}
/* step 3: output the columns */
nrows = (nset + ncols - 1) / ncols;
for (i = 0; i < nrows; i++)
{
for (j = 0; j < ncols; j++)
{
/* if we hit the end of the options, quit */
k = i + j * nrows;
if (k >= nset)
{
break;
}
/* output this option's value */
width = 0;
switch (opts[todump[k]].type)
{
case BOOL:
if (!*opts[todump[k]].value)
{
qaddch('n');
qaddch('o');
width = 2;
}
qaddstr(opts[todump[k]].name);
width += strlen(opts[todump[k]].name);
break;
case NUM:
sprintf(nbuf, "%-3d", UCHAR(*opts[todump[k]].value));
qaddstr(opts[todump[k]].name);
qaddch('=');
qaddstr(nbuf);
width = 4 + strlen(opts[todump[k]].name);
break;
case STR:
qaddstr(opts[todump[k]].name);
qaddch('=');
qaddch('"');
strcpy(tmpblk.c, opts[todump[k]].value);
width = 3 + strlen(tmpblk.c);
if (width > MAXWIDTH)
{
width = MAXWIDTH;
strcpy(tmpblk.c + MAXWIDTH - 6, "...");
}
qaddstr(tmpblk.c);
qaddch('"');
width += strlen(opts[todump[k]].name);
break;
}
/* pad the field to the correct size */
if (k + nrows <= nset)
{
while (width < widths[j] + 2)
{
qaddch(' ');
width++;
}
}
}
addch('\n');
exrefresh();
}
#else
int i;
int col;
char nbuf[4];
for (i = col = 0; opts[i].name; i++)
{
/* if not set and not all, ignore this option */
if (!all && !(opts[i].flags & SET))
{
continue;
}
/* align this option in one of the columns */
if (col > 52)
{
addch('\n');
col = 0;
}
else if (col > 26)
{
while (col < 52)
{
qaddch(' ');
col++;
}
}
else if (col > 0)
{
while (col < 26)
{
qaddch(' ');
col++;
}
}
switch (opts[i].type)
{
case BOOL:
if (!*opts[i].value)
{
qaddch('n');
qaddch('o');
col += 2;
}
qaddstr(opts[i].name);
col += strlen(opts[i].name);
break;
case NUM:
sprintf(nbuf, "%-3d", UCHAR(*opts[i].value));
qaddstr(opts[i].name);
qaddch('=');
qaddstr(nbuf);
col += 4 + strlen(opts[i].name);
break;
case STR:
qaddstr(opts[i].name);
qaddch('=');
qaddch('"');
qaddstr(opts[i].value);
qaddch('"');
col += 3 + strlen(opts[i].name) + strlen(opts[i].value);
break;
}
exrefresh();
}
if (col > 0)
{
addch('\n');
exrefresh();
}
#endif
}
#ifndef NO_MKEXRC
/* This function saves the current configuarion of options to a file */
void saveopts(fd)
int fd; /* file descriptor to write to */
{
int i;
char buf[256], *pos;
/* write each set options */
for (i = 0; opts[i].name; i++)
{
/* if unset or unsettable, ignore this option */
if (!(opts[i].flags & SET) || !(opts[i].flags & CANSET))
{
continue;
}
strcpy(buf, "set ");
pos = &buf[4];
switch (opts[i].type)
{
case BOOL:
if (!*opts[i].value)
{
*pos++='n';
*pos++='o';
}
strcpy(pos, opts[i].name);
strcat(pos, "\n");
break;
case NUM:
sprintf(pos, "%s=%-3d\n", opts[i].name, *opts[i].value & 0xff);
break;
case STR:
sprintf(pos, "%s=\"%s\"\n", opts[i].name, opts[i].value);
break;
}
twrite(fd, buf, strlen(buf));
}
}
#endif
/* This function changes the values of one or more options. */
void setopts(assignments)
char *assignments; /* a string containing option assignments */
{
char *name; /* name of variable in assignments */
char *value; /* value of the variable */
char *scan; /* used for moving through strings */
int i, j;
/* for each assignment... */
for (name = assignments; *name; )
{
/* skip whitespace */
if (*name == ' ' || *name == '\t')
{
name++;
continue;
}
/* find the value, if any */
for (scan = name; *scan >= 'a' && *scan <= 'z'; scan++)
{
}
if (*scan == '=')
{
*scan++ = '\0';
if (*scan == '"')
{
value = ++scan;
while (*scan && *scan != '"')
{
scan++;
}
if (*scan)
{
*scan++ = '\0';
}
}
else
{
value = scan;
while (*scan && *scan != ' ' && *scan != '\t')
{
scan++;
}
if (*scan)
{
*scan++ = '\0';
}
}
}
else
{
if (*scan)
{
*scan++ = '\0';
}
value = NULL;
if (name[0] == 'n' && name[1] == 'o')
{
name += 2;
}
}
/* find the variable */
for (i = 0;
opts[i].name && strcmp(opts[i].name, name) && strcmp(opts[i].nm, name);
i++)
{
}
/* change the variable */
if (!opts[i].name)
{
msg("invalid option name \"%s\"", name);
}
else if ((opts[i].flags & CANSET) != CANSET)
{
msg("option \"%s\" can't be altered", name);
}
else if ((opts[i].flags & RCSET) != CANSET && nlines >= 1L)
{
msg("option \"%s\" can only be set in a %s file", name, EXRC);
}
else if (value)
{
switch (opts[i].type)
{
case BOOL:
msg("option \"[no]%s\" is boolean", name);
break;
case NUM:
j = atoi(value);
if (j == 0 && *value != '0')
{
msg("option \"%s\" must have a numeric value", name);
}
else if (j < opts[i].value[1] || j > (opts[i].value[2] & 0xff))
{
msg("option \"%s\" must have a value between %d and %d",
name, opts[i].value[1], opts[i].value[2] & 0xff);
}
else
{
*opts[i].value = atoi(value);
opts[i].flags |= SET;
}
break;
case STR:
strcpy(opts[i].value, value);
opts[i].flags |= SET;
break;
}
if (opts[i].flags & MR)
{
mustredraw = TRUE;
}
}
else /* valid option, no value */
{
if (opts[i].type == BOOL)
{
*opts[i].value = (name[-1] != 'o');
opts[i].flags |= SET;
if (opts[i].flags & MR)
{
mustredraw = TRUE;
}
}
else
{
msg("option \"%s\" must be given a value", name);
}
}
/* move on to the next option */
name = scan;
}
/* special processing ... */
/* if "readonly" then set the READONLY flag for this file */
if (*o_readonly)
{
setflag(file, READONLY);
}
}